/*
 * Copyright (c) 2022 Kirky
 * Licensed under the Open Software Licence, Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/osl-3.0.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lingeringdream.luciole.model.ability;

import com.lingeringdream.luciole.model.entity.Achievement;
import com.lingeringdream.luciole.model.helper.ValuesBucketHelper;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.content.Intent;
import ohos.data.DatabaseHelper;
import ohos.data.dataability.DataAbilityPredicates;
import ohos.data.dataability.DataAbilityUtils;
import ohos.data.orm.OrmContext;
import ohos.data.orm.OrmObjectObserver;
import ohos.data.orm.OrmPredicates;
import ohos.data.rdb.ValuesBucket;
import ohos.data.resultset.ResultSet;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.utils.net.Uri;

/**
 * @author Kirky
 * @version 1.0
 * @date 2022/4/29
 */
public class AchieveDataAbility extends Ability {
    private static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0xD001005, AchieveDataAbility.class.getSimpleName());
    private static final String DB_NAME = "LucioleBase.db";
    private static final String DB_NAME_ALIAS = "LucioleBase";
    private static final String DB_TABLE_NAME = "Achievement";
    /**
     * 观察者
     */
    private final OrmObjectObserver contextOrmObjectObserver = (changeContext, subAllChange) ->
            HiLog.info(LABEL_LOG, "onChange Context");

    /**
     * 访问指针
     */
    private OrmContext ormContext;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        HiLog.info(LABEL_LOG, "AchievementDataAbility onStart");
        DatabaseHelper helper = new DatabaseHelper(this);
        ormContext = helper.getOrmContext(DB_NAME_ALIAS, DB_NAME, com.lingeringdream.luciole.model.LucioleBaseDb.class);
    }

    @Override
    public void onStop()  {
        super.onStop();
        HiLog.info(LABEL_LOG, "AchievementDataAbility onStop");
        ormContext.close();
    }

    /**
     * 查询Achievement实例
     *
     * @param predicates 先决查询条件
     * @return 查询到的用户实例集，若无则返回为空
     */
    @Override
    public ResultSet query(Uri uri, String[] columns, DataAbilityPredicates predicates) {
        HiLog.info(LABEL_LOG, DB_NAME_ALIAS + "-" + DB_TABLE_NAME + ": query");
        if (ormContext == null) {
            HiLog.error(LABEL_LOG, "failed to query, ormContext is null");
            return null;
        }
        OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates, Achievement.class);
        try {
            ResultSet classifications = ormContext.query(ormPredicates, columns);
            if (classifications == null) {
                HiLog.info(LABEL_LOG, DB_NAME_ALIAS + "-" + DB_TABLE_NAME + ": no data!");
                return null;
            }
            return classifications;
        } catch (Exception e) {
            HiLog.error(LABEL_LOG, e.getLocalizedMessage());
            return null;
        }
    }

    /**
     * 插入一个新Achievement实例
     *
     * @param uri
     * @param value
     * @return 插入后的id
     */
    @Override
    public int insert(Uri uri, ValuesBucket value) {
        HiLog.info(LABEL_LOG, DB_NAME_ALIAS + "-" + DB_TABLE_NAME + ": insert");
//         参数校验
        if (ormContext == null) {
            HiLog.error(LABEL_LOG, "failed to insert, ormContext is null");
            return -1;
        }

        // 构造插入数据
        Achievement achievement = ValuesBucketHelper.bucket2Achievement(value);

        try {
            // 插入数据库
            boolean isSuccessful = ormContext.insert(achievement);
            if (!isSuccessful) {
                HiLog.error(LABEL_LOG, "failed to insert");
                return -1;
            }
            isSuccessful = ormContext.flush();
            if (!isSuccessful) {
                HiLog.error(LABEL_LOG, "failed to insert flush");
                return -1;
            }
            DataAbilityHelper.creator(this, uri).notifyChange(uri);
            return Math.toIntExact(achievement.getRowId());
        } catch (Exception e) {
            HiLog.error(LABEL_LOG, e.getLocalizedMessage());
            return -1;
        }
    }

    /**
     * 删除Achievement实例
     *
     * @param uri
     * @param predicates 先决查询条件
     * @return
     */
    @Override
    public int delete(Uri uri, DataAbilityPredicates predicates) {
        HiLog.info(LABEL_LOG, DB_NAME_ALIAS + "-" + DB_TABLE_NAME + ": delete");
//         参数校验
        if (ormContext == null) {
            HiLog.error(LABEL_LOG, "failed to delete, ormContext is null");
            return -1;
        }
        try {
            OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates, Achievement.class);
            int value = ormContext.delete(ormPredicates);
            DataAbilityHelper.creator(this, uri).notifyChange(uri);
            return value;
        } catch (Exception e) {
            HiLog.error(LABEL_LOG, e.getLocalizedMessage());
            return -1;
        }
    }


    /**
     * 更新数据库User表
     *
     * @param uri
     * @param value
     * @return
     */
    @Override
    public int update(Uri uri, ValuesBucket value, DataAbilityPredicates predicates) {
        HiLog.info(LABEL_LOG, DB_NAME_ALIAS + "-" + DB_TABLE_NAME + ": update");
//         参数校验
        if (ormContext == null) {
            HiLog.error(LABEL_LOG, "failed to update, ormContext is null");
            return -1;
        }
        try {
            OrmPredicates ormPredicates = DataAbilityUtils.createOrmPredicates(predicates, Achievement.class);
            int index = ormContext.update(ormPredicates, value);
            HiLog.info(LABEL_LOG, "UserDataAbility update value:" + index);
            DataAbilityHelper.creator(this, uri).notifyChange(uri);
            return index;
        } catch (Exception e) {
            HiLog.error(LABEL_LOG, e.getLocalizedMessage());
            return -1;
        }
    }
}
